package com.ncmem.controller;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.ncmem.down3.biz.FolderBuilder;
import com.ncmem.up7.biz.FolderScaner;
import com.ncmem.up7.biz.FolderSchema;
import com.ncmem.up7.database.DBConfig;
import com.ncmem.up7.database.sql.SqlFile;
import com.ncmem.up7.database.DBFolder;
import com.ncmem.up7.sql.*;
import com.ncmem.utils.ConfigReader;
import com.ncmem.utils.DataBaseType;
import com.ncmem.utils.JsonDateValueProcessor;
import com.ncmem.utils.PathTool;
import com.ncmem.up7.database.sql.SqlFolder;
import com.ncmem.up7.biz.PathGuidBuilder;
import com.ncmem.up7.biz.up7_biz_event;
import com.ncmem.model.FileInf;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;

@RestController
public class FileMgrApi {
    /**
     * 加载根目录下的数据
     * @param uid
     * @param pid
     * @param pathRel
     * @return
     */
    public String loadRootData(String uid,String pid,String pathRel) throws SQLException, InstantiationException, ParseException, IllegalAccessException {
        List<FileInf> files = SqlTable.build("up7_files").reads(FileInf.build(),
                "f_id,f_pid,f_nameLoc,f_sizeLoc,f_lenLoc,f_time,f_pidRoot,f_fdTask,f_pathSvr,f_pathRel,f_object_key",
                SqlWhere.build()
                        .eq("f_uid",uid)
                        .eq("f_complete",true)
                        .eq("f_deleted",false)
                        .eq("f_fdChild",false),
                SqlSort.build().desc("f_fdTask").desc("f_time")
        );

        HashMap map = new HashMap();
        map.put("count", files.size());
        map.put("code", 0);
        map.put("msg", "");
        map.put("data", files.toArray());
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();
        String json = gson.toJson(map); //开始转换

        System.out.println(json);
        return json;
    }

    /**
     * 加载子目录数据
     * @return
     */
    public String loadChildData(String uid,String pid,String pathRel) throws SQLException, InstantiationException, ParseException, IllegalAccessException {
        String pathRelSql = String.format("f_pathRel='%s'+f_nameLoc",pathRel);
        if(ConfigReader.dbType() != DataBaseType.SqlServer)
            pathRelSql = String.format("f_pathRel=CONCAT('%s',f_nameLoc)",pathRel);

        //加载文件列表
        List<FileInf> files = SqlTable.build("up7_files").reads(FileInf.build(),
                "f_id,f_pid,f_nameLoc,f_sizeLoc,f_lenLoc,f_time,f_pidRoot,f_fdTask,f_pathSvr,f_pathRel,f_object_key",
                SqlWhere.build().
                        eq("f_uid",uid).eq("f_complete",true)
                        .eq("f_deleted",false)
                        .eq("f_fdChild",true)
                        .sql("f_pathRel",pathRelSql),
                SqlSort.build().desc("f_fdTask").desc("f_time")
        );

        //加载子目录
        List<FileInf> folders = SqlTable.build("up7_folders").reads(FileInf.build(),
                "f_id,f_nameLoc,f_pid,f_sizeLoc,f_time,f_pidRoot,f_pathRel",
                SqlWhere.build().
                        eq("f_uid",uid)
                        .eq("f_complete",true)
                        .eq("f_deleted",false)
                        .sql("f_pathRel",pathRelSql),
                SqlSort.build().desc("f_time")
        );

        for (FileInf f : folders)
        {
            f.fdTask=true;
            f.fdChild=false;
            files.add(0,f);
        }

        HashMap map = new HashMap();
        map.put("count", files.size());
        map.put("code", 0);
        map.put("msg", "");
        map.put("data", files.toArray());
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();
        String json = gson.toJson(map); //开始转换

        System.out.println(json);
        return json;
    }

    /**
     * 加载文件列表数据，
     * @param pid 父级ID
     * @param uid 用户ID
     * @return
     */
    @RequestMapping(value="filemgr/data",method = RequestMethod.GET)
    @ResponseBody
    public String data(@RequestParam(value="pid", required=false,defaultValue="")String pid,
                       @RequestParam(value="uid", required=false,defaultValue="")String uid,
                       @RequestParam(value="pathRel", required=false,defaultValue="")String pathRel
    ) throws SQLException, InstantiationException, ParseException, IllegalAccessException {
        pathRel = PathTool.url_decode(pathRel);
        if(!pathRel.endsWith("/")) pathRel+="/";
        //根目录
        if (StringUtils.equals(pathRel,"/") ) return  this.loadRootData(uid,pid,pathRel);
        else return this.loadChildData(uid,pid,pathRel);
    }

    /**
     * 搜索文件列表数据，
     * @param pid 父级ID
     * @param uid 用户ID
     * @param pageSize     页大小
     * @param pageIndex    页索引
     * @return
     */
    @RequestMapping(value="filemgr/search",method = RequestMethod.GET)
    public String search(@RequestParam(value="pid", required=false,defaultValue="")String pid,
                         @RequestParam(value="uid", required=false,defaultValue="0")String uid,
                         @RequestParam(value="limit", required=false,defaultValue="")String pageSize,
                         @RequestParam(value="page", required=false,defaultValue="")String pageIndex,
                         @RequestParam(value="pathRel", required=false,defaultValue="")String pathRel,
                         @RequestParam(value="key", required=false,defaultValue="")String key
    ) throws SQLException, InstantiationException, ParseException, IllegalAccessException {
        pathRel = PathTool.url_decode(pathRel);
        if (!pathRel.endsWith("/")) pathRel += '/';
        boolean isRootDir = StringUtils.equals(pathRel,"/");
        key = PathTool.url_decode(key);

        //f_pathRel = 'a' + f_nameLoc
        String pathRelSql = String.format("f_pathRel='%s'+f_nameLoc",pathRel);
        if(ConfigReader.dbType() != DataBaseType.SqlServer)
            pathRelSql = String.format("f_pathRel=CONCAT('%s',f_nameLoc)",pathRel);
        if(isRootDir) pathRelSql="";

        //从文件表中搜索
        List<FileInf> files = SqlTable.build("up7_files").reads(FileInf.build(),
                "f_id,f_pid,f_nameLoc,f_sizeLoc,f_lenLoc,f_time,f_pidRoot,f_fdTask,f_pathSvr,f_pathRel",
                SqlWhere.build()
                        .sql("f_pathRel",pathRelSql)
                        .sql("key",String.format("f_nameLoc like '%%%s%%'",key))
                        .eq("f_uid",uid)
                        .eq("f_complete",true)
                        .eq("f_deleted",false),
                SqlSort.build().desc("f_fdTask").desc("f_time")
        );

        //从目录表中搜索
        List<FileInf> fds = SqlTable.build("up7_folders").reads(FileInf.build(),
                "f_id,f_nameLoc,f_pid,f_sizeLoc,f_time,f_pidRoot,f_pathRel",
                SqlWhere.build()
                        .sql("f_pathRel",pathRelSql)
                        .sql("key",String.format("f_nameLoc like '%%%s%%'",key))
                        .eq("f_uid",uid)
                        .eq("f_complete",true)
                        .eq("f_deleted",false),
                SqlSort.build().desc("f_time")
        );

        for (FileInf f : fds)
        {
            f.fdTask=true;
            files.add(0,f);
        }

        HashMap map = new HashMap();
        map.put("count", files.size());
        map.put("code", 0);
        map.put("msg", "");
        map.put("data", files.toArray());
        Gson gson = new GsonBuilder()
                .setDateFormat("yyyy-MM-dd HH:mm:ss")
                .create();
        String json = gson.toJson(map); //开始转换

        System.out.println(json);
        return json;
    }

    /**
     * 重命名文件或目录
     * @param id 文件或目录ID
     * @param fdTask 是否是文件夹
     * @param pathRel 相对路径
     * @param nameNew 新名称
     * @return
     */
    @RequestMapping(value="filemgr/rename",method = RequestMethod.GET)
    public String rename(@RequestParam(value="id", required=false,defaultValue="")String id,
                         @RequestParam(value="fdTask", required=false,defaultValue="")Boolean fdTask,
                         @RequestParam(value="pathRel", required=false,defaultValue="")String pathRel,
                         @RequestParam(value="nameLoc", required=false,defaultValue="")String nameNew
    ) throws ParseException, IllegalAccessException, SQLException {
        id = id.trim();
        pathRel = PathTool.url_decode(pathRel);
        nameNew = PathTool.url_decode(nameNew);

        String parentDir = PathTool.getParent(pathRel);
        parentDir = parentDir.replace('\\', '/');
        //根目录
        boolean isRootDir = StringUtils.equals(parentDir,"/");

        //文件
        if(!fdTask) return this.rename_file(id,pathRel,nameNew);
            //子目录
        else if(!isRootDir) return this.renameChildDir(id,pathRel,nameNew);
        else return this.renameRootDir(id,pathRel,nameNew);
    }

    /**
     * 重命名文件
     * @param id      文件ID
     * @param pathRel 相对路径
     * @param name    文件名称
     * @return
     */
    public String rename_file(String id,String pathRel,String name) throws ParseException, IllegalAccessException, SQLException {
        //新的相对路径
        pathRel = PathTool.getParent(pathRel);
        pathRel = PathTool.combin(pathRel, name);

        //根据相对路径(新)=>查找同名文件
        FileInf s = SqlTable.build("up7_files").readOne(FileInf.build(),
                SqlWhere.build()
                        .eq("f_pathRel",pathRel)
                        .eq("f_deleted",false));

        boolean exist = s != null;

        //不存在同名文件
        if (!exist)
        {
            SqlTable.build("up7_files").update(
                    SqlSeter.build().set("f_nameLoc",name)
                            .set("f_nameSvr",name)
                            .set("f_pathRel",pathRel),
                    SqlWhere.build().eq("f_id",id)
            );

            JSONObject v = new JSONObject();
            v.put("state", true);
            v.put("pathRel",pathRel);
            return v.toString();
        }
        else
        {
            JSONObject v = new JSONObject();
            v.put("state", false);
            v.put("msg", "存在同名文件");
            v.put("code", "102");
            return v.toString();
        }
    }

    /**
     * 重命名根目录
     * @param id
     * @param pathRel
     * @param name
     * @return
     * @throws ParseException
     * @throws IllegalAccessException
     * @throws SQLException
     */
    public String renameRootDir(String id,String pathRel,String name) throws ParseException, IllegalAccessException, SQLException {
        String pathRelOld = pathRel;
        //新的相对路径
        String pathRelNew = "/" + name;
        FileInf s = SqlTable.build("up7_files").readOne(FileInf.build(),
                SqlWhere.build()
                        .eq("f_pathRel",pathRelNew)
                        .eq("f_deleted",false));

        boolean exist = s != null;

        //不存在同名目录
        if(!exist)
        {
            //更新文件夹相对路径，名称
            SqlTable.build("up7_files").update(
                    SqlSeter.build()
                            .set("f_nameLoc",name)
                            .set("f_nameSvr",name)
                            .set("f_pathRel",pathRelNew),
                    SqlWhere.build().eq("f_id",id)
            );

            SqlFile.build().updatePathRel(pathRelOld, pathRelNew);
            SqlFolder.build().updatePathRel(pathRelOld, pathRelNew);

            JSONObject v = new JSONObject();
            v.put("state", true);
            v.put("pathRel",pathRelNew);
            return v.toString();
        }//存在同名目录
        else
        {
            JSONObject res = new JSONObject();
            res.put("state", false);
            res.put("msg", "存在同名项");
            return  res.toString();
        }
    }

    /**
     * 重命名子目录
     * @param id
     * @param pathRel
     * @param name
     * @return
     * @throws ParseException
     * @throws IllegalAccessException
     * @throws SQLException
     */
    public String renameChildDir(String id,String pathRel,String name) throws ParseException, IllegalAccessException, SQLException {
        String pathRelOld = pathRel;
        //root/dir/name => root/dir
        Integer index = pathRel.lastIndexOf('/');
        pathRel = pathRel.substring(0, index + 1);
        //root/dir/old => root/dir/new
        pathRel += name;
        String pathRelNew = pathRel;

        FileInf fd = SqlTable.build("up7_folders").readOne(FileInf.build(),
                "f_pathRel",
                SqlWhere.build()
                        .eq("f_pathRel",pathRelNew)
                        .eq("f_deleted",false)
        );

        boolean exist = fd != null;
        //同名目录不存在=>可以重命名
        if(!exist)
        {
            //更新当前目录相对路径
            SqlTable.build("up7_folders").update(
                    SqlSeter.build()
                            .set("f_nameLoc",name)
                            .set("f_pathRel",pathRelNew),
                    SqlWhere.build().eq("f_id",id)
            );

            //更新子文件和子目录相对路径
            SqlFile.build().updatePathRel(pathRelOld, pathRelNew);
            SqlFolder.build().updatePathRel(pathRelOld, pathRelNew);

            JSONObject v = new JSONObject();
            v.put("state", true);
            v.put("pathRel",pathRelNew);
            return v.toString();

        }//存在同名目录
        else{
            JSONObject v = new JSONObject();
            v.put("state", false);
            v.put("msg", "存在同名目录");
            v.put("code", "102");
            return v.toString();
        }
    }

    /**
     * 删除目录或目录
     * @param id 文件或目录ID，由前端提供
     * @return
     */
    @RequestMapping(value = "filemgr/del",method = RequestMethod.GET)
    public String del(@RequestParam(value="id", required=false,defaultValue="")String id,
                      @RequestParam(value="pathRel", required=false,defaultValue="")String pathRel)
    {
        pathRel = PathTool.url_decode(pathRel);
        pathRel += '/';

        SqlWhereMerge swm = new SqlWhereMerge();
        DBConfig cfg = new DBConfig();
        if(StringUtils.equals(cfg.m_db, "sql"))
        {
            swm.charindex(pathRel,"f_pathRel");
        }
        else
        {
            swm.instr(pathRel,"f_pathRel");
        }
        String where = swm.to_sql();

        SqlExec se = new SqlExec();
        se.update("up7_files", new SqlParam[] {new SqlParam("f_deleted",true)}, where);
        se.update("up7_files"
                , new SqlParam[] {new SqlParam("f_deleted",true)}
                , new SqlParam[] {new SqlParam("f_id",id)}
        );
        se.update("up7_folders", new SqlParam[] {new SqlParam("f_deleted",true)}, where);
        se.update("up7_folders"
                , new SqlParam[] {new SqlParam("f_deleted",true)}
                , new SqlParam[] {new SqlParam("f_id",id)}
        );

        JSONObject ret = new JSONObject();
        ret.put("ret", 1);
        return ret.toString();
    }

    /**
     * 批量删除文件或目录
     * @param data
     * @return
     */
    @RequestMapping(value = "filemgr/del_batch",method = RequestMethod.GET)
    String del_batch(@RequestParam(value = "data",required = false,defaultValue = "")String data)
    {
        data = PathTool.url_decode(data);
        JSONArray o = JSONArray.fromObject(data);

        SqlExec se = new SqlExec();
        se.exec_batch("up7_files", "update up7_files set f_deleted=1 where f_id=?", "", "f_id", o);
        se.exec_batch("up7_folders", "update up7_folders set f_deleted=1 where f_id=?", "", "f_id", o);

        JSONObject ret = new JSONObject();
        ret.put("ret", 1);
        return ret.toString();
    }

    /**
     * 获取当前目录路径
     * @param data
     * @return
     */
    @RequestMapping(value="filemgr/path",method = RequestMethod.GET)
    @ResponseBody
    public String path(@RequestParam(value="data", required=false,defaultValue="")String data
    )
    {
        data = PathTool.url_decode(data);
        JSONObject fd = JSONObject.fromObject(data);

        SqlFolder df = new SqlFolder();
        return df.build_path(fd);
    }

    /**
     * 生成导航路径
     * @param data
     * @return
     */
    @RequestMapping(value = "filemgr/build_path",method = RequestMethod.GET)
    String build_path(@RequestParam(value = "data",required = false,defaultValue = "")String data)
    {
        data = PathTool.url_decode(data);
        JSONObject fd = JSONObject.fromObject(data);

        SqlFolder df = new SqlFolder();
        return df.build_path(fd);
    }

    /**
     * 创建目录
     * @param pid 父ID，前端提供
     * @param pathRel 相对路径，前端提供
     * @return
     */
    @RequestMapping(value = "filemgr/mkdir",method = RequestMethod.GET)
    public String mkdir(@RequestParam(value="f_nameLoc", required=false,defaultValue="")String name,
                            @RequestParam(value="f_pid", required=false,defaultValue="")String pid,
                            @RequestParam(value="f_uid", required=false,defaultValue="")String uid,
                            @RequestParam(value="f_pidRoot", required=false,defaultValue="")String pidRoot,
                            @RequestParam(value="f_pathRel", required=false,defaultValue="")String pathRel
    ) throws ParseException, IllegalAccessException, SQLException {
        name = PathTool.url_decode(name);
        pathRel = PathTool.url_decode(pathRel);
        boolean isRootDir = StringUtils.equals(pathRel,"/");
        pathRel = PathTool.combin(pathRel, name);

        SqlFolder df = SqlFolder.build();
        if (df.exist_same_folder(pathRel))
        {
            JSONObject ret = new JSONObject();
            ret.put("ret", false);
            ret.put("msg", "已存在同名目录");
            return ret.toString();
        }

        FileInf dir = new FileInf();
        dir.id = PathTool.guid();
        dir.pid = pid;
        dir.uid = uid;
        dir.pidRoot = pidRoot;
        dir.nameLoc = name;
        dir.nameSvr = name;
        dir.complete = true;
        dir.fdTask = true;
        dir.pathRel = pathRel;

        //根目录
        if (isRootDir)
        {
            SqlFile.build().add(dir);
        }//子目录
        else
        {
            SqlFolder.build().add(dir);
        }
        JSONObject ret = JSONObject.fromObject(dir);
        ret.put("ret", true);
        return ret.toString();
    }

    /**
     * 加载未上传完的任务列表
     * @return
     */
    @RequestMapping(value = "filemgr/uncomp",method = RequestMethod.GET)
    String uncomp()
    {
        SqlExec se = new SqlExec();
        JSONArray files = se.exec("up7_files"
                , "select f_id as id,f_nameLoc as nameLoc,f_pathLoc as pathLoc,f_sizeLoc as sizeLoc,f_lenSvr as lenSvr,f_perSvr as perSvr,f_fdTask as fdTask from up7_files where f_complete=0 and f_fdChild=0 and f_deleted=0"
                , "f_id,f_nameLoc,f_pathLoc,f_sizeLoc,f_lenSvr,f_perSvr,f_fdTask"
                , "id,nameLoc,pathLoc,sizeLoc,lenSvr,perSvr,fdTask");
        return files.toString();
    }

    /**
     * 加载未下载完的任务列表
     * @param uid 用户ID，前端提供
     * @return
     */
    @RequestMapping(value = "filemgr/uncmp_down",method = RequestMethod.GET)
    String uncmp_down(@RequestParam(value = "uid",required = false,defaultValue = "0")String uid)
    {
        SqlExec se = new SqlExec();
        JSONArray files = se.select("down3_files"
                , "f_id,f_nameLoc,f_pathLoc,f_perLoc,f_sizeSvr,f_fdTask"
                , new SqlParam[] {new SqlParam("f_uid",uid)}
                , ""
        );
        return files.toString();
    }

    /**
     * 文件初始化，验证同名文件。
     * @param uid
     * @param pathRel
     * @param pathLoc
     * @param cbk
     * @param id
     * @param lenLoc
     * @param md5
     * @param pid
     * @param pidRoot
     * @param sizeLoc
     * @return
     */
    @RequestMapping(value = "filemgr/f_create",method = RequestMethod.GET)
    String f_create(@RequestParam(value = "pid",required = false,defaultValue = "")String pid,
                    @RequestParam(value = "pidRoot",required = false,defaultValue = "")String pidRoot,
                    @RequestParam(value = "md5",required = false,defaultValue = "")String md5,
                    @RequestParam(value = "id",required = false,defaultValue = "")String id,
                    @RequestParam(value = "uid",required = false,defaultValue = "0")String uid,
                    @RequestParam(value = "lenLoc",required = false,defaultValue = "0")Long lenLoc,
                    @RequestParam(value = "sizeLoc",required = false,defaultValue = "")String sizeLoc,
                    @RequestParam(value = "blockSize",required = false,defaultValue = "0")String blockSize,
                    @RequestParam(value = "callback",required = false,defaultValue = "")String cbk,
                    @RequestParam(value = "pathLoc",required = false,defaultValue = "")String pathLoc,
                    @RequestParam(value = "pathRel",required = false,defaultValue = "")String pathRel
    ) throws ParseException, IllegalAccessException, SQLException {
        //客户端使用的是encodeURIComponent编码，
        pathLoc = PathTool.url_decode(pathLoc);//utf-8解码
        pathRel = PathTool.url_decode(pathRel);

        //参数为空
        if (   StringUtils.isEmpty(sizeLoc))
        {
            return cbk + "({\"value\":null})" ;
        }

        FileInf fileSvr = new FileInf();
        fileSvr.uid = uid;//将当前文件UID设置为当前用户UID
        fileSvr.id = id;
        fileSvr.pid = pid;
        fileSvr.pidRoot = pidRoot;
        boolean isRootFile = StringUtils.equals(pathRel,"/");
        fileSvr.fdChild = !isRootFile;
        fileSvr.nameLoc = PathTool.getName(pathLoc);
        fileSvr.pathLoc = pathLoc;
        fileSvr.pathRel = PathTool.combin(pathRel, fileSvr.nameLoc);
        fileSvr.lenLoc = lenLoc;
        fileSvr.sizeLoc = sizeLoc;
        fileSvr.deleted = false;
        fileSvr.md5 = md5;
        fileSvr.blockSize=Integer.parseInt(blockSize);
        fileSvr.nameSvr = fileSvr.nameLoc;

        //所有单个文件均以uuid/file方式存储
        PathGuidBuilder pb = new PathGuidBuilder();
        try {
            fileSvr.pathSvr = pb.genFile(fileSvr);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //同名文件检测
        /*if (SqlFile.existSameFile(fileSvr.nameLoc, fileSvr.pid))
        {
            String data = cbk + "({'value':'','ret':false,'code':'101'})";
            return data;
        }*/

        //
        SqlFile df = new SqlFile();
        df.add(fileSvr);

        //触发事件
        up7_biz_event.file_create(fileSvr);

        Gson gson = new Gson();
        String json = gson.toJson(fileSvr);
        json = PathTool.url_encode(json);
        json = cbk + "({\"value\":\"" + json + "\",\"ret\":true})";//返回jsonp格式数据。
        return json;
    }

    /**
     * 文件上传完毕，在文件上传完毕后由前端调用。
     * 调用位置：up6.file.js-post_complete
     * @param id 文件ID，由控件生成，GUID 示例：04fdfc13fc2a4b7a9d0682f8c344926f
     * @param uid 用户ID，在JS中困于
     * @param callback JQ回调
     * @return
     */
    @RequestMapping(value="filemgr/f_complete",method = RequestMethod.GET)
    @ResponseBody
    public String f_complete(@RequestParam(value="id", required=false,defaultValue="")String id,
                             @RequestParam(value="uid", required=false,defaultValue="0")String uid,
                             @RequestParam(value="callback", required=false,defaultValue="")String callback,
                             @RequestParam(value="cover", required=false,defaultValue="0")Integer cover
    ) throws ParseException, IllegalAccessException, SQLException {
        //返回值。1表示成功
        int ret = 0;
        if ( !StringUtils.isBlank(id))
        {
            SqlFile db = SqlFile.build();
            db.complete(id,uid);
            FileInf file = db.read(id);

            //覆盖同名文件-更新同名文件状态
            if(cover == 1) db.delete(file.pathRel, uid, id);

            up7_biz_event.file_post_complete(id);
            ret = 1;
        }
        return callback + "(" + ret + ")";
    }

    /**
     * 文件夹初始化
     * @param pid
     * @param pidRoot
     * @param md5
     * @param id
     * @param uid
     * @param lenLoc
     * @param sizeLoc
     * @param cbk
     * @param pathLoc
     * @param pathRel
     * @return
     */
    @RequestMapping(value = "filemgr/fd_create",method = RequestMethod.GET)
    String fd_create(@RequestParam(value = "pid",required = false,defaultValue = "")String pid,
                     @RequestParam(value = "id",required = false,defaultValue = "")String id,
                     @RequestParam(value = "sizeLoc",required = false,defaultValue = "")String sizeLoc,
                    @RequestParam(value = "pidRoot",required = false,defaultValue = "")String pidRoot,
                    @RequestParam(value = "md5",required = false,defaultValue = "")String md5,
                    @RequestParam(value = "uid",required = false,defaultValue = "0")String uid,
                     @RequestParam(value = "filesCount",required = false,defaultValue = "0")Integer fileCount,
                    @RequestParam(value = "lenLoc",required = false,defaultValue = "0")Long lenLoc,
                    @RequestParam(value = "callback",required = false,defaultValue = "")String cbk,
                    @RequestParam(value = "pathLoc",required = false,defaultValue = "")String pathLoc,
                    @RequestParam(value = "pathRel",required = false,defaultValue = "")String pathRel
    ) throws ParseException, IllegalAccessException, SQLException {
        pathRel = PathTool.url_decode(pathRel);
        pathLoc = PathTool.url_decode(pathLoc);

        //参数为空
        if (    StringUtils.isBlank(id)||
                StringUtils.isBlank(pathLoc))
        {
            return cbk + "({\"value\":null})";
        }

        FileInf fileSvr = new FileInf();
        fileSvr.id      = id;
        fileSvr.pid     = pid;
        fileSvr.pidRoot = pidRoot;
        fileSvr.fdChild = false;
        fileSvr.fdTask  = true;
        fileSvr.uid     = uid;
        fileSvr.nameLoc = PathTool.getName(pathLoc);
        fileSvr.pathLoc = pathLoc;
        fileSvr.pathRel = PathTool.combin(pathRel, fileSvr.nameLoc);
        fileSvr.lenLoc  = lenLoc;
        fileSvr.fileCount = fileCount;
        fileSvr.sizeLoc = sizeLoc;
        fileSvr.deleted = false;
        fileSvr.nameSvr = fileSvr.nameLoc;

        //生成路径，格式：upload/年/月/日/guid/文件夹名称
        PathGuidBuilder pb = new PathGuidBuilder();
        try {
            fileSvr.pathSvr = pb.genFolder(fileSvr.uid, fileSvr.id,fileSvr.nameLoc);
        } catch (IOException e) {
            e.printStackTrace();
        }
        fileSvr.pathSvr = fileSvr.pathSvr.replace("\\", "/");
        PathTool.mkdir(fileSvr.pathSvr);

        //创建层级结构
        FolderSchema fs = new FolderSchema();
        fs.create(fileSvr);

        //添加到根目录
        if(StringUtils.equals(pathRel,"/")) SqlFile.build().add(fileSvr);
        else SqlFolder.build().add(fileSvr);

        //触发事件
        up7_biz_event.folder_create(fileSvr);

        Gson gson   = new Gson();
        String json = gson.toJson(fileSvr);
        json = PathTool.url_encode(json);

        JSONObject ret = new JSONObject();
        ret.put("value",json);
        ret.put("ret",true);
        json = cbk + String.format("(%s)",ret.toString());//返回jsonp格式数据。
        return json;
    }

    /**
     * 文件夹上传完毕，文件夹上传结束后调用
     * @return
     */
    @RequestMapping(value="filemgr/fd_complete",method = RequestMethod.GET)
    @ResponseBody
    public String fd_complete(
            @RequestParam(value="id", required=false,defaultValue="")String id,
            @RequestParam(value="pathRel", required=false,defaultValue="")String pathRel,
            @RequestParam(value="uid", required=false,defaultValue="0")String uid,
            @RequestParam(value="callback", required=false,defaultValue="")String cbk,
            @RequestParam(value="cover", required=false,defaultValue="0")Integer cover
    ) throws IOException, SQLException, ParseException, IllegalAccessException {
        int ret = 0;

        //参数为空
        if (	!StringUtils.isBlank(id))
        {
            pathRel = PathTool.url_decode(pathRel);
            //是根目录
            boolean isRootDir = StringUtils.equals(pathRel,"/");
            FileInf folder = null;
            FileInf fdExist = null;

            //子目录
            if(!isRootDir)
            {
                folder = SqlFolder.build().read(id);
                fdExist = SqlFolder.build().read(folder.pathRel,id);

                //存在相同目录=>删除旧目录
                if(fdExist != null) SqlFolder.build().del(fdExist.id,uid);
            }//根目录
            else{
                folder = SqlFile.build().read(id);
                fdExist = SqlFile.build().read(folder.pathRel,id,uid);

                //存在相同目录=>删除旧目录
                if(fdExist != null) SqlFile.build().Delete(uid,fdExist.id);
            }

            if(fdExist !=null)
            {
                folder.id = fdExist.id;
                folder.pid = fdExist.pid;
                folder.pidRoot = fdExist.pidRoot;
            }

            //根节点
            FileInf root = new FileInf();
            root.id = folder.pidRoot;
            root.uid = folder.uid;
            //当前节点是根节点
            if( StringUtils.isBlank(root.id)) root.id = folder.id;

            //从文件中解析层级结构信息
            FolderScaner fsd = new FolderScaner();
            //覆盖已有项
            fsd.m_cover = fdExist!=null;
            fsd.save(folder);

            //子目录上传完毕
            if(!isRootDir) SqlFolder.build().complete(id);
                //根目录
            else SqlFile.build().complete(id,uid);

            up7_biz_event.folder_post_complete(id);

            ret = 1;
        }
        return cbk + "(" + ret + ")";
    }

    /**
     * 获取文件夹数据，
     * @param id
     * @param callback
     * @return
     */
    @RequestMapping(value="filemgr/fd_data",method = RequestMethod.GET)
    @ResponseBody
    public String fd_data(@RequestParam(value="id", required=false,defaultValue="")String id,
                          @RequestParam(value="callback", required=false,defaultValue="")String callback
    )
    {

        if (StringUtils.isBlank(id))
        {
            return callback + "({\"value\":null})";
        }

        FolderBuilder fb = new FolderBuilder();
        Gson gson = new Gson();
        String json = gson.toJson(fb.build(id));
        json = PathTool.url_encode(json);
        json = callback + "({\"value\":\"" + json + "\"})";//返回jsonp格式数据。
        return json;
    }

    /**
     * 获取目录文件总数
     * @param id 目录ID
     * @return
     */
    @RequestMapping(value = "filemgr/count",method = RequestMethod.GET)
    String fd_data_count( @RequestParam(value = "id",required = false,defaultValue = "")String id
    )
    {
        if (StringUtils.isEmpty(id)) return "";

        FolderBuilder fb = new FolderBuilder();
        Integer c = fb.count(id);
        long totalSz = fb.totalSize(id);
        JSONObject obj = new JSONObject();
        obj.put("count", c);
        obj.put("totalSize", totalSz);

        return obj.toString();
    }
}
